﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using EONFULLSIN2.Core;
using EONFULLSIN2.Models.Dto.Device;
using EONFULLSIN2.Core.Helpers;
using EONFULLSIN2.Models.Enum.SensorPoint;
using EONFULLSIN2.Models.Enum.IOPointEnum;
using EONFULLSIN2.Core.Extensions;
using EONFULLSIN2.Models.Attributes;

namespace EONFULLSIN2.Services.Device.JuYing
{
    /// <summary>
    /// 务必注册成单例
    /// </summary>
    public class JuYingModbusService : ModbusBaseServices ,IJuYingModbusService
    {
        private static byte slaveId = 1;// Modbus 从站 ID，通常为 1
        private static ushort startAddress = 0;// 从哪个寄存器地址开始读取
        private static ushort numRegisters = 32;// 要读取的寄存器数量（例如，读取 28 个寄存器）

        public override string IpAddress { protected set; get; } = "192.168.1.232";

        public override int Port { protected set; get; } = 10000;

        /// <summary>
        /// 温度枚举列表
        /// </summary>
        public List<eTempPointEnum?> TempPointEnums => Enum.GetValues(typeof(eTempPointEnum)).Cast<eTempPointEnum?>().ToList();
        /// <summary>
        /// 压力枚举列表
        /// </summary>
        public List<ePressurePointEnum?> PressurePointEnums => Enum.GetValues(typeof(ePressurePointEnum)).Cast<ePressurePointEnum?>().ToList();

        public async Task<List<SensorItemDto>> GetSensorDataAsync() {
            List<SensorItemDto> sensorItemDtos = new List<SensorItemDto>();
            if (IsConnect) {
                var readData = await ReadInputRegistersAsync(slaveId, startAddress, numRegisters);

                if (readData != null && readData.Length > 0) {
                    for (int i = 0; i < readData.Length; i++) {
                        SensorItemDto sensorItemDto = new SensorItemDto();
                        sensorItemDto.ID = i;
                        sensorItemDto.DataSourceAddress = i;

                        double readValue = readData[i];
                        var eTemp = TempPointEnums.FirstOrDefault(o => o.GetAttributeOfType<SensorPointAttribute>().ChannelIndex == i);
                        var ePre = PressurePointEnums.FirstOrDefault(o => o.GetAttributeOfType<SensorPointAttribute>().ChannelIndex == i);

                        SensorPointAttribute sensorPointAttribute = default;
                        if (eTemp != null) {

                            sensorPointAttribute = eTemp.GetAttributeOfType<SensorPointAttribute>();
                            sensorItemDto.Type = Models.Enum.eSensorTypeEnum.Temperature;

                        } else if (ePre != null) {

                            sensorPointAttribute = ePre.GetAttributeOfType<SensorPointAttribute>();
                            sensorItemDto.Type = Models.Enum.eSensorTypeEnum.Pressure;

                        } else {

                            sensorItemDto.Type = Models.Enum.eSensorTypeEnum.Temperature;

                        }

                        if (sensorPointAttribute != null) {
                            readValue = ParseHelper.MapValue((double)readData[i] / 1000, sensorPointAttribute.Smin, sensorPointAttribute.Smax, sensorPointAttribute.Imin, sensorPointAttribute.Imax);
                            //readValue = (double)readData[i] / 1000;
                            sensorItemDto.CodeNumber = sensorPointAttribute.ChannelName;
                            sensorItemDto.Description = sensorPointAttribute?.Description ?? "";
                            sensorItemDto.Name = sensorPointAttribute?.Name ?? "";
                            sensorItemDto.IsEnable = sensorPointAttribute?.IsEnable ?? false;
                        }

                        sensorItemDto.Value = readValue;
                        sensorItemDtos.Add(sensorItemDto);
                    }
                } else {
                    LogManager.Error($"未读取到寄存器数据，startIndex：{startAddress}，readCount：{numRegisters}");
                }
            }
            return sensorItemDtos;
        }


        public async Task<double> GetSensorDataByIndexAsync(eTempPointEnum eTempPointEnum) {

            if (IsConnect)
            {
                var arrt = eTempPointEnum.GetAttributeOfType<SensorPointAttribute>();
                var startIndex = (ushort)arrt.ChannelIndex;
                var readCount = (ushort)1;
                var readData = await ReadInputRegistersAsync(slaveId, startIndex, readCount);
                if (readData != null && readData.Length > 0)
                {
                    return ParseHelper.MapValue(readData[0], arrt.Smin, arrt.Smax, arrt.Imin, arrt.Imax);

                }
                else
                {
                    LogManager.Error($"未读取到寄存器数据，startIndex：{startIndex}，readCount：{readCount}");
                }
            }
            throw new Exception($"{IpAddress}:{Port},is not connect");
        }
    }
}
